{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "mS0bWISTqhMI",
        "outputId": "3539bf35-ccff-45b3-a8b1-013219f1dbec"
      },
      "outputs": [
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "Using backend: pytorch\n",
            "/usr/local/lib/python3.6/dist-packages/statsmodels/tools/_testing.py:19: FutureWarning: pandas.util.testing is deprecated. Use the functions in the public API at pandas.testing instead.\n",
            "  import pandas.util.testing as tm\n"
          ]
        }
      ],
      "source": [
        "import dgl.nn as dglnn\n",
        "from dgl import from_networkx\n",
        "import torch.nn as nn\n",
        "import torch as th\n",
        "import torch.nn.functional as F\n",
        "import dgl.function as fn\n",
        "import networkx as nx\n",
        "import pandas as pd\n",
        "import socket\n",
        "import struct\n",
        "import random\n",
        "from sklearn.preprocessing import LabelEncoder\n",
        "from sklearn.preprocessing import StandardScaler\n",
        "from sklearn.model_selection import train_test_split\n",
        "import category_encoders as ce\n",
        "from sklearn.decomposition import PCA\n",
        "import seaborn as sns\n",
        "import matplotlib.pyplot as plt\n",
        "import numpy as np"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "id": "ki0watiErdJp"
      },
      "outputs": [],
      "source": [
        "data = pd.read_csv('NF-BoT-IoT.csv')"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 439
        },
        "id": "0JmyVopVrqWQ",
        "outputId": "1d57507e-d714-402e-8aa5-37e378101020"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>IPV4_SRC_ADDR</th>\n",
              "      <th>L4_SRC_PORT</th>\n",
              "      <th>IPV4_DST_ADDR</th>\n",
              "      <th>L4_DST_PORT</th>\n",
              "      <th>PROTOCOL</th>\n",
              "      <th>L7_PROTO</th>\n",
              "      <th>IN_BYTES</th>\n",
              "      <th>OUT_BYTES</th>\n",
              "      <th>IN_PKTS</th>\n",
              "      <th>OUT_PKTS</th>\n",
              "      <th>TCP_FLAGS</th>\n",
              "      <th>FLOW_DURATION_MILLISECONDS</th>\n",
              "      <th>Label</th>\n",
              "      <th>Attack</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>192.168.100.6</td>\n",
              "      <td>52670</td>\n",
              "      <td>192.168.100.1</td>\n",
              "      <td>53</td>\n",
              "      <td>17</td>\n",
              "      <td>5.212</td>\n",
              "      <td>71</td>\n",
              "      <td>126</td>\n",
              "      <td>1</td>\n",
              "      <td>1</td>\n",
              "      <td>0</td>\n",
              "      <td>4294966</td>\n",
              "      <td>0</td>\n",
              "      <td>Benign</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>192.168.100.6</td>\n",
              "      <td>49160</td>\n",
              "      <td>192.168.100.149</td>\n",
              "      <td>4444</td>\n",
              "      <td>6</td>\n",
              "      <td>0.000</td>\n",
              "      <td>217753000</td>\n",
              "      <td>199100</td>\n",
              "      <td>4521</td>\n",
              "      <td>4049</td>\n",
              "      <td>24</td>\n",
              "      <td>4176249</td>\n",
              "      <td>1</td>\n",
              "      <td>Theft</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>192.168.100.46</td>\n",
              "      <td>3456</td>\n",
              "      <td>192.168.100.5</td>\n",
              "      <td>80</td>\n",
              "      <td>17</td>\n",
              "      <td>0.000</td>\n",
              "      <td>8508021</td>\n",
              "      <td>8918372</td>\n",
              "      <td>9086</td>\n",
              "      <td>9086</td>\n",
              "      <td>0</td>\n",
              "      <td>4175916</td>\n",
              "      <td>0</td>\n",
              "      <td>Benign</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>192.168.100.3</td>\n",
              "      <td>80</td>\n",
              "      <td>192.168.100.55</td>\n",
              "      <td>8080</td>\n",
              "      <td>6</td>\n",
              "      <td>7.000</td>\n",
              "      <td>8442138</td>\n",
              "      <td>9013406</td>\n",
              "      <td>9086</td>\n",
              "      <td>9086</td>\n",
              "      <td>0</td>\n",
              "      <td>4175916</td>\n",
              "      <td>0</td>\n",
              "      <td>Benign</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>192.168.100.46</td>\n",
              "      <td>80</td>\n",
              "      <td>192.168.100.5</td>\n",
              "      <td>80</td>\n",
              "      <td>6</td>\n",
              "      <td>7.000</td>\n",
              "      <td>8374706</td>\n",
              "      <td>0</td>\n",
              "      <td>9086</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>4175916</td>\n",
              "      <td>0</td>\n",
              "      <td>Benign</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>...</th>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>600095</th>\n",
              "      <td>192.168.100.46</td>\n",
              "      <td>80</td>\n",
              "      <td>192.168.100.5</td>\n",
              "      <td>80</td>\n",
              "      <td>6</td>\n",
              "      <td>7.000</td>\n",
              "      <td>2330065</td>\n",
              "      <td>0</td>\n",
              "      <td>2523</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>4263037</td>\n",
              "      <td>0</td>\n",
              "      <td>Benign</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>600096</th>\n",
              "      <td>192.168.100.5</td>\n",
              "      <td>0</td>\n",
              "      <td>192.168.100.3</td>\n",
              "      <td>0</td>\n",
              "      <td>6</td>\n",
              "      <td>0.000</td>\n",
              "      <td>1054423</td>\n",
              "      <td>0</td>\n",
              "      <td>1513</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>4263062</td>\n",
              "      <td>0</td>\n",
              "      <td>Benign</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>600097</th>\n",
              "      <td>192.168.100.7</td>\n",
              "      <td>365</td>\n",
              "      <td>192.168.100.3</td>\n",
              "      <td>565</td>\n",
              "      <td>17</td>\n",
              "      <td>0.000</td>\n",
              "      <td>62422</td>\n",
              "      <td>0</td>\n",
              "      <td>1357</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>4263062</td>\n",
              "      <td>0</td>\n",
              "      <td>Benign</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>600098</th>\n",
              "      <td>192.168.100.3</td>\n",
              "      <td>50850</td>\n",
              "      <td>13.54.166.67</td>\n",
              "      <td>8883</td>\n",
              "      <td>6</td>\n",
              "      <td>222.178</td>\n",
              "      <td>11300</td>\n",
              "      <td>1664</td>\n",
              "      <td>32</td>\n",
              "      <td>32</td>\n",
              "      <td>24</td>\n",
              "      <td>4264935</td>\n",
              "      <td>0</td>\n",
              "      <td>Benign</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>600099</th>\n",
              "      <td>192.168.100.6</td>\n",
              "      <td>49160</td>\n",
              "      <td>192.168.100.149</td>\n",
              "      <td>4444</td>\n",
              "      <td>6</td>\n",
              "      <td>0.000</td>\n",
              "      <td>40102320</td>\n",
              "      <td>37280</td>\n",
              "      <td>763</td>\n",
              "      <td>590</td>\n",
              "      <td>24</td>\n",
              "      <td>4270068</td>\n",
              "      <td>1</td>\n",
              "      <td>Theft</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "<p>600100 rows × 14 columns</p>\n",
              "</div>"
            ],
            "text/plain": [
              "         IPV4_SRC_ADDR  L4_SRC_PORT  ... Label  Attack\n",
              "0        192.168.100.6        52670  ...     0  Benign\n",
              "1        192.168.100.6        49160  ...     1   Theft\n",
              "2       192.168.100.46         3456  ...     0  Benign\n",
              "3        192.168.100.3           80  ...     0  Benign\n",
              "4       192.168.100.46           80  ...     0  Benign\n",
              "...                ...          ...  ...   ...     ...\n",
              "600095  192.168.100.46           80  ...     0  Benign\n",
              "600096   192.168.100.5            0  ...     0  Benign\n",
              "600097   192.168.100.7          365  ...     0  Benign\n",
              "600098   192.168.100.3        50850  ...     0  Benign\n",
              "600099   192.168.100.6        49160  ...     1   Theft\n",
              "\n",
              "[600100 rows x 14 columns]"
            ]
          },
          "execution_count": 3,
          "metadata": {
            "tags": []
          },
          "output_type": "execute_result"
        }
      ],
      "source": [
        "data"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "id": "PoVYaeFZtJBd"
      },
      "outputs": [],
      "source": [
        "data['IPV4_SRC_ADDR'] = data.IPV4_SRC_ADDR.apply(lambda x: socket.inet_ntoa(struct.pack('>I', random.randint(0xac100001, 0xac1f0001))))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "metadata": {
        "id": "zs4z58WCtu8k"
      },
      "outputs": [],
      "source": [
        "data['IPV4_SRC_ADDR'] = data.IPV4_SRC_ADDR.apply(str)\n",
        "data['L4_SRC_PORT'] = data.L4_SRC_PORT.apply(str)\n",
        "data['IPV4_DST_ADDR'] = data.IPV4_DST_ADDR.apply(str)\n",
        "data['L4_DST_PORT'] = data.L4_DST_PORT.apply(str)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "metadata": {
        "id": "9EEwTAK3tle9"
      },
      "outputs": [],
      "source": [
        "data['IPV4_SRC_ADDR'] = data['IPV4_SRC_ADDR'] + ':' + data['L4_SRC_PORT']\n",
        "data['IPV4_DST_ADDR'] = data['IPV4_DST_ADDR'] + ':' + data['L4_DST_PORT']"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "metadata": {
        "id": "xbdaHUxOtzd-"
      },
      "outputs": [],
      "source": [
        "data.drop(columns=['L4_SRC_PORT','L4_DST_PORT'],inplace=True)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 439
        },
        "id": "CN9rLLmr0eeI",
        "outputId": "b0d9ee9b-3642-4542-92b8-41ec68edeb26"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>IPV4_SRC_ADDR</th>\n",
              "      <th>IPV4_DST_ADDR</th>\n",
              "      <th>PROTOCOL</th>\n",
              "      <th>L7_PROTO</th>\n",
              "      <th>IN_BYTES</th>\n",
              "      <th>OUT_BYTES</th>\n",
              "      <th>IN_PKTS</th>\n",
              "      <th>OUT_PKTS</th>\n",
              "      <th>TCP_FLAGS</th>\n",
              "      <th>FLOW_DURATION_MILLISECONDS</th>\n",
              "      <th>Label</th>\n",
              "      <th>Attack</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>172.16.136.22:52670</td>\n",
              "      <td>192.168.100.1:53</td>\n",
              "      <td>17</td>\n",
              "      <td>5.212</td>\n",
              "      <td>71</td>\n",
              "      <td>126</td>\n",
              "      <td>1</td>\n",
              "      <td>1</td>\n",
              "      <td>0</td>\n",
              "      <td>4294966</td>\n",
              "      <td>0</td>\n",
              "      <td>Benign</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>172.19.122.45:49160</td>\n",
              "      <td>192.168.100.149:4444</td>\n",
              "      <td>6</td>\n",
              "      <td>0.000</td>\n",
              "      <td>217753000</td>\n",
              "      <td>199100</td>\n",
              "      <td>4521</td>\n",
              "      <td>4049</td>\n",
              "      <td>24</td>\n",
              "      <td>4176249</td>\n",
              "      <td>1</td>\n",
              "      <td>Theft</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>172.19.178.98:3456</td>\n",
              "      <td>192.168.100.5:80</td>\n",
              "      <td>17</td>\n",
              "      <td>0.000</td>\n",
              "      <td>8508021</td>\n",
              "      <td>8918372</td>\n",
              "      <td>9086</td>\n",
              "      <td>9086</td>\n",
              "      <td>0</td>\n",
              "      <td>4175916</td>\n",
              "      <td>0</td>\n",
              "      <td>Benign</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>172.27.217.67:80</td>\n",
              "      <td>192.168.100.55:8080</td>\n",
              "      <td>6</td>\n",
              "      <td>7.000</td>\n",
              "      <td>8442138</td>\n",
              "      <td>9013406</td>\n",
              "      <td>9086</td>\n",
              "      <td>9086</td>\n",
              "      <td>0</td>\n",
              "      <td>4175916</td>\n",
              "      <td>0</td>\n",
              "      <td>Benign</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>172.17.161.166:80</td>\n",
              "      <td>192.168.100.5:80</td>\n",
              "      <td>6</td>\n",
              "      <td>7.000</td>\n",
              "      <td>8374706</td>\n",
              "      <td>0</td>\n",
              "      <td>9086</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>4175916</td>\n",
              "      <td>0</td>\n",
              "      <td>Benign</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>...</th>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>600095</th>\n",
              "      <td>172.16.170.111:80</td>\n",
              "      <td>192.168.100.5:80</td>\n",
              "      <td>6</td>\n",
              "      <td>7.000</td>\n",
              "      <td>2330065</td>\n",
              "      <td>0</td>\n",
              "      <td>2523</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>4263037</td>\n",
              "      <td>0</td>\n",
              "      <td>Benign</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>600096</th>\n",
              "      <td>172.16.99.96:0</td>\n",
              "      <td>192.168.100.3:0</td>\n",
              "      <td>6</td>\n",
              "      <td>0.000</td>\n",
              "      <td>1054423</td>\n",
              "      <td>0</td>\n",
              "      <td>1513</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>4263062</td>\n",
              "      <td>0</td>\n",
              "      <td>Benign</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>600097</th>\n",
              "      <td>172.19.110.55:365</td>\n",
              "      <td>192.168.100.3:565</td>\n",
              "      <td>17</td>\n",
              "      <td>0.000</td>\n",
              "      <td>62422</td>\n",
              "      <td>0</td>\n",
              "      <td>1357</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>4263062</td>\n",
              "      <td>0</td>\n",
              "      <td>Benign</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>600098</th>\n",
              "      <td>172.20.134.141:50850</td>\n",
              "      <td>13.54.166.67:8883</td>\n",
              "      <td>6</td>\n",
              "      <td>222.178</td>\n",
              "      <td>11300</td>\n",
              "      <td>1664</td>\n",
              "      <td>32</td>\n",
              "      <td>32</td>\n",
              "      <td>24</td>\n",
              "      <td>4264935</td>\n",
              "      <td>0</td>\n",
              "      <td>Benign</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>600099</th>\n",
              "      <td>172.24.119.121:49160</td>\n",
              "      <td>192.168.100.149:4444</td>\n",
              "      <td>6</td>\n",
              "      <td>0.000</td>\n",
              "      <td>40102320</td>\n",
              "      <td>37280</td>\n",
              "      <td>763</td>\n",
              "      <td>590</td>\n",
              "      <td>24</td>\n",
              "      <td>4270068</td>\n",
              "      <td>1</td>\n",
              "      <td>Theft</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "<p>600100 rows × 12 columns</p>\n",
              "</div>"
            ],
            "text/plain": [
              "               IPV4_SRC_ADDR         IPV4_DST_ADDR  ...  Label  Attack\n",
              "0        172.16.136.22:52670      192.168.100.1:53  ...      0  Benign\n",
              "1        172.19.122.45:49160  192.168.100.149:4444  ...      1   Theft\n",
              "2         172.19.178.98:3456      192.168.100.5:80  ...      0  Benign\n",
              "3           172.27.217.67:80   192.168.100.55:8080  ...      0  Benign\n",
              "4          172.17.161.166:80      192.168.100.5:80  ...      0  Benign\n",
              "...                      ...                   ...  ...    ...     ...\n",
              "600095     172.16.170.111:80      192.168.100.5:80  ...      0  Benign\n",
              "600096        172.16.99.96:0       192.168.100.3:0  ...      0  Benign\n",
              "600097     172.19.110.55:365     192.168.100.3:565  ...      0  Benign\n",
              "600098  172.20.134.141:50850     13.54.166.67:8883  ...      0  Benign\n",
              "600099  172.24.119.121:49160  192.168.100.149:4444  ...      1   Theft\n",
              "\n",
              "[600100 rows x 12 columns]"
            ]
          },
          "execution_count": 8,
          "metadata": {
            "tags": []
          },
          "output_type": "execute_result"
        }
      ],
      "source": [
        "data"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "metadata": {
        "id": "C_WU15ngvnBM"
      },
      "outputs": [],
      "source": [
        "data.drop(columns=['Attack'],inplace = True)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "metadata": {
        "id": "Q0d3nbdiv37j"
      },
      "outputs": [],
      "source": [
        "data.rename(columns={\"Label\": \"label\"},inplace = True)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "metadata": {
        "id": "SVgjPVfg03XG"
      },
      "outputs": [],
      "source": [
        "label = data.label"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "metadata": {
        "id": "ADl2Fj7H08Rr"
      },
      "outputs": [],
      "source": [
        "data.drop(columns=['label'],inplace = True)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "metadata": {
        "id": "qhsZMD3uwLk7"
      },
      "outputs": [],
      "source": [
        "scaler = StandardScaler()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "metadata": {
        "id": "aukoVdNf2zcp"
      },
      "outputs": [],
      "source": [
        "data =  pd.concat([data, label], axis=1)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 439
        },
        "id": "IP-ZEZW4nxSm",
        "outputId": "e00c48bf-d374-4cd6-86d2-ecd75877f928"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>IPV4_SRC_ADDR</th>\n",
              "      <th>IPV4_DST_ADDR</th>\n",
              "      <th>PROTOCOL</th>\n",
              "      <th>L7_PROTO</th>\n",
              "      <th>IN_BYTES</th>\n",
              "      <th>OUT_BYTES</th>\n",
              "      <th>IN_PKTS</th>\n",
              "      <th>OUT_PKTS</th>\n",
              "      <th>TCP_FLAGS</th>\n",
              "      <th>FLOW_DURATION_MILLISECONDS</th>\n",
              "      <th>label</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>172.16.136.22:52670</td>\n",
              "      <td>192.168.100.1:53</td>\n",
              "      <td>17</td>\n",
              "      <td>5.212</td>\n",
              "      <td>71</td>\n",
              "      <td>126</td>\n",
              "      <td>1</td>\n",
              "      <td>1</td>\n",
              "      <td>0</td>\n",
              "      <td>4294966</td>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>172.19.122.45:49160</td>\n",
              "      <td>192.168.100.149:4444</td>\n",
              "      <td>6</td>\n",
              "      <td>0.000</td>\n",
              "      <td>217753000</td>\n",
              "      <td>199100</td>\n",
              "      <td>4521</td>\n",
              "      <td>4049</td>\n",
              "      <td>24</td>\n",
              "      <td>4176249</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>172.19.178.98:3456</td>\n",
              "      <td>192.168.100.5:80</td>\n",
              "      <td>17</td>\n",
              "      <td>0.000</td>\n",
              "      <td>8508021</td>\n",
              "      <td>8918372</td>\n",
              "      <td>9086</td>\n",
              "      <td>9086</td>\n",
              "      <td>0</td>\n",
              "      <td>4175916</td>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>172.27.217.67:80</td>\n",
              "      <td>192.168.100.55:8080</td>\n",
              "      <td>6</td>\n",
              "      <td>7.000</td>\n",
              "      <td>8442138</td>\n",
              "      <td>9013406</td>\n",
              "      <td>9086</td>\n",
              "      <td>9086</td>\n",
              "      <td>0</td>\n",
              "      <td>4175916</td>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>172.17.161.166:80</td>\n",
              "      <td>192.168.100.5:80</td>\n",
              "      <td>6</td>\n",
              "      <td>7.000</td>\n",
              "      <td>8374706</td>\n",
              "      <td>0</td>\n",
              "      <td>9086</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>4175916</td>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>...</th>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>600095</th>\n",
              "      <td>172.16.170.111:80</td>\n",
              "      <td>192.168.100.5:80</td>\n",
              "      <td>6</td>\n",
              "      <td>7.000</td>\n",
              "      <td>2330065</td>\n",
              "      <td>0</td>\n",
              "      <td>2523</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>4263037</td>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>600096</th>\n",
              "      <td>172.16.99.96:0</td>\n",
              "      <td>192.168.100.3:0</td>\n",
              "      <td>6</td>\n",
              "      <td>0.000</td>\n",
              "      <td>1054423</td>\n",
              "      <td>0</td>\n",
              "      <td>1513</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>4263062</td>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>600097</th>\n",
              "      <td>172.19.110.55:365</td>\n",
              "      <td>192.168.100.3:565</td>\n",
              "      <td>17</td>\n",
              "      <td>0.000</td>\n",
              "      <td>62422</td>\n",
              "      <td>0</td>\n",
              "      <td>1357</td>\n",
              "      <td>0</td>\n",
              "      <td>0</td>\n",
              "      <td>4263062</td>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>600098</th>\n",
              "      <td>172.20.134.141:50850</td>\n",
              "      <td>13.54.166.67:8883</td>\n",
              "      <td>6</td>\n",
              "      <td>222.178</td>\n",
              "      <td>11300</td>\n",
              "      <td>1664</td>\n",
              "      <td>32</td>\n",
              "      <td>32</td>\n",
              "      <td>24</td>\n",
              "      <td>4264935</td>\n",
              "      <td>0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>600099</th>\n",
              "      <td>172.24.119.121:49160</td>\n",
              "      <td>192.168.100.149:4444</td>\n",
              "      <td>6</td>\n",
              "      <td>0.000</td>\n",
              "      <td>40102320</td>\n",
              "      <td>37280</td>\n",
              "      <td>763</td>\n",
              "      <td>590</td>\n",
              "      <td>24</td>\n",
              "      <td>4270068</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "<p>600100 rows × 11 columns</p>\n",
              "</div>"
            ],
            "text/plain": [
              "               IPV4_SRC_ADDR  ... label\n",
              "0        172.16.136.22:52670  ...     0\n",
              "1        172.19.122.45:49160  ...     1\n",
              "2         172.19.178.98:3456  ...     0\n",
              "3           172.27.217.67:80  ...     0\n",
              "4          172.17.161.166:80  ...     0\n",
              "...                      ...  ...   ...\n",
              "600095     172.16.170.111:80  ...     0\n",
              "600096        172.16.99.96:0  ...     0\n",
              "600097     172.19.110.55:365  ...     0\n",
              "600098  172.20.134.141:50850  ...     0\n",
              "600099  172.24.119.121:49160  ...     1\n",
              "\n",
              "[600100 rows x 11 columns]"
            ]
          },
          "execution_count": 15,
          "metadata": {
            "tags": []
          },
          "output_type": "execute_result"
        }
      ],
      "source": [
        "data"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "metadata": {
        "id": "PUa4uJbewQc7"
      },
      "outputs": [],
      "source": [
        "X_train, X_test, y_train, y_test = train_test_split(\n",
        "     data, label, test_size=0.3, random_state=123,stratify= label)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "z3DrIWDHqNxp",
        "outputId": "2cd5cf77-365b-4bb2-cf31-059964f6a6dc"
      },
      "outputs": [
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "/usr/local/lib/python3.6/dist-packages/category_encoders/utils.py:21: FutureWarning: is_categorical is deprecated and will be removed in a future version.  Use is_categorical_dtype instead\n",
            "  elif pd.api.types.is_categorical(cols):\n"
          ]
        }
      ],
      "source": [
        "encoder = ce.TargetEncoder(cols=['TCP_FLAGS','L7_PROTO','PROTOCOL'])\n",
        "encoder.fit(X_train, y_train)\n",
        "X_train = encoder.transform(X_train)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 18,
      "metadata": {
        "id": "EDKYHCbcqN81"
      },
      "outputs": [],
      "source": [
        "cols_to_norm = list(set(list(X_train.iloc[:, 2:].columns ))  - set(list(['label'])) )\n",
        "X_train[cols_to_norm] = scaler.fit_transform(X_train[cols_to_norm])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 19,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 439
        },
        "id": "-TkDCimdrHXQ",
        "outputId": "8905cfb8-f2fe-44ed-91b4-ee98577a946c"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>IPV4_SRC_ADDR</th>\n",
              "      <th>IPV4_DST_ADDR</th>\n",
              "      <th>PROTOCOL</th>\n",
              "      <th>L7_PROTO</th>\n",
              "      <th>IN_BYTES</th>\n",
              "      <th>OUT_BYTES</th>\n",
              "      <th>IN_PKTS</th>\n",
              "      <th>OUT_PKTS</th>\n",
              "      <th>TCP_FLAGS</th>\n",
              "      <th>FLOW_DURATION_MILLISECONDS</th>\n",
              "      <th>label</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>398456</th>\n",
              "      <td>172.16.54.186:47768</td>\n",
              "      <td>192.168.100.7:2043</td>\n",
              "      <td>0.242607</td>\n",
              "      <td>0.041512</td>\n",
              "      <td>-0.017305</td>\n",
              "      <td>-0.008442</td>\n",
              "      <td>-0.045637</td>\n",
              "      <td>-0.027054</td>\n",
              "      <td>0.343039</td>\n",
              "      <td>0.496716</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>189579</th>\n",
              "      <td>172.18.59.187:41228</td>\n",
              "      <td>192.168.100.5:1011</td>\n",
              "      <td>0.242607</td>\n",
              "      <td>0.041512</td>\n",
              "      <td>-0.017305</td>\n",
              "      <td>-0.008442</td>\n",
              "      <td>-0.045637</td>\n",
              "      <td>-0.027054</td>\n",
              "      <td>0.343039</td>\n",
              "      <td>0.496716</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>463036</th>\n",
              "      <td>172.25.238.190:36130</td>\n",
              "      <td>192.168.100.3:5801</td>\n",
              "      <td>0.242607</td>\n",
              "      <td>0.041512</td>\n",
              "      <td>-0.017276</td>\n",
              "      <td>-0.008442</td>\n",
              "      <td>-0.045637</td>\n",
              "      <td>-0.027054</td>\n",
              "      <td>0.343039</td>\n",
              "      <td>0.496716</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>324954</th>\n",
              "      <td>172.20.41.245:45196</td>\n",
              "      <td>192.168.100.7:1277</td>\n",
              "      <td>0.242607</td>\n",
              "      <td>0.041512</td>\n",
              "      <td>-0.017305</td>\n",
              "      <td>-0.008442</td>\n",
              "      <td>-0.045637</td>\n",
              "      <td>-0.027054</td>\n",
              "      <td>0.343039</td>\n",
              "      <td>0.496716</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>185030</th>\n",
              "      <td>172.25.9.193:48136</td>\n",
              "      <td>192.168.100.3:2190</td>\n",
              "      <td>0.242607</td>\n",
              "      <td>0.041512</td>\n",
              "      <td>-0.017305</td>\n",
              "      <td>-0.008442</td>\n",
              "      <td>-0.045637</td>\n",
              "      <td>-0.027054</td>\n",
              "      <td>0.343039</td>\n",
              "      <td>0.496716</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>...</th>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>169412</th>\n",
              "      <td>172.17.114.147:41020</td>\n",
              "      <td>192.168.100.5:6666</td>\n",
              "      <td>0.242607</td>\n",
              "      <td>0.041512</td>\n",
              "      <td>-0.017305</td>\n",
              "      <td>-0.008442</td>\n",
              "      <td>-0.045637</td>\n",
              "      <td>-0.027054</td>\n",
              "      <td>0.343039</td>\n",
              "      <td>0.496714</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>522250</th>\n",
              "      <td>172.22.53.208:3780</td>\n",
              "      <td>192.168.100.3:1</td>\n",
              "      <td>0.242607</td>\n",
              "      <td>-3.014581</td>\n",
              "      <td>-0.017313</td>\n",
              "      <td>-0.008442</td>\n",
              "      <td>-0.045637</td>\n",
              "      <td>-0.027054</td>\n",
              "      <td>-0.876614</td>\n",
              "      <td>0.496716</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>218225</th>\n",
              "      <td>172.16.208.148:45576</td>\n",
              "      <td>192.168.100.3:7741</td>\n",
              "      <td>0.242607</td>\n",
              "      <td>0.041512</td>\n",
              "      <td>-0.017305</td>\n",
              "      <td>-0.008442</td>\n",
              "      <td>-0.045637</td>\n",
              "      <td>-0.027054</td>\n",
              "      <td>0.343039</td>\n",
              "      <td>0.496716</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1072</th>\n",
              "      <td>172.29.232.100:42920</td>\n",
              "      <td>192.168.100.3:80</td>\n",
              "      <td>0.242607</td>\n",
              "      <td>0.254635</td>\n",
              "      <td>-0.016184</td>\n",
              "      <td>-0.007523</td>\n",
              "      <td>-0.029495</td>\n",
              "      <td>-0.009069</td>\n",
              "      <td>-0.096099</td>\n",
              "      <td>0.489584</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>273601</th>\n",
              "      <td>172.26.130.1:58427</td>\n",
              "      <td>192.168.100.7:49153</td>\n",
              "      <td>0.242607</td>\n",
              "      <td>0.041512</td>\n",
              "      <td>-0.017305</td>\n",
              "      <td>-0.008442</td>\n",
              "      <td>-0.045637</td>\n",
              "      <td>-0.027054</td>\n",
              "      <td>0.343039</td>\n",
              "      <td>0.496716</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "<p>420070 rows × 11 columns</p>\n",
              "</div>"
            ],
            "text/plain": [
              "               IPV4_SRC_ADDR  ... label\n",
              "398456   172.16.54.186:47768  ...     1\n",
              "189579   172.18.59.187:41228  ...     1\n",
              "463036  172.25.238.190:36130  ...     1\n",
              "324954   172.20.41.245:45196  ...     1\n",
              "185030    172.25.9.193:48136  ...     1\n",
              "...                      ...  ...   ...\n",
              "169412  172.17.114.147:41020  ...     1\n",
              "522250    172.22.53.208:3780  ...     1\n",
              "218225  172.16.208.148:45576  ...     1\n",
              "1072    172.29.232.100:42920  ...     1\n",
              "273601    172.26.130.1:58427  ...     1\n",
              "\n",
              "[420070 rows x 11 columns]"
            ]
          },
          "execution_count": 19,
          "metadata": {
            "tags": []
          },
          "output_type": "execute_result"
        }
      ],
      "source": [
        "X_train"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 20,
      "metadata": {
        "id": "ek535MkWwUHN"
      },
      "outputs": [],
      "source": [
        "X_train['h'] = X_train[ cols_to_norm ].values.tolist()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 21,
      "metadata": {
        "id": "OIrcNfMSwa0j"
      },
      "outputs": [],
      "source": [
        "G = nx.from_pandas_edgelist(X_train, \"IPV4_SRC_ADDR\", \"IPV4_DST_ADDR\", ['h','label'],create_using=nx.MultiGraph())"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 22,
      "metadata": {
        "id": "QluLSxbiwn7M"
      },
      "outputs": [],
      "source": [
        "G = G.to_directed()\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 23,
      "metadata": {
        "id": "2zClkKEzwrVb"
      },
      "outputs": [],
      "source": [
        "G = from_networkx(G,edge_attrs=['h','label'] )\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 24,
      "metadata": {
        "id": "9jlBYgE8wsW7"
      },
      "outputs": [],
      "source": [
        "# Eq1\n",
        "G.ndata['h'] = th.ones(G.num_nodes(), G.edata['h'].shape[1])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 25,
      "metadata": {
        "id": "E7Vc6IELwuJr"
      },
      "outputs": [],
      "source": [
        "G.edata['train_mask'] = th.ones(len(G.edata['h']), dtype=th.bool)\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 26,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "BIx7-W6s46Ju",
        "outputId": "5dbe6d1f-61c9-4d25-b7c8-26cd7694a33b"
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "tensor([True, True, True,  ..., True, True, True])"
            ]
          },
          "execution_count": 26,
          "metadata": {
            "tags": []
          },
          "output_type": "execute_result"
        }
      ],
      "source": [
        "G.edata['train_mask'] "
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 27,
      "metadata": {
        "id": "DzDap1MR5e95"
      },
      "outputs": [],
      "source": [
        "def compute_accuracy(pred, labels):\n",
        "    return (pred.argmax(1) == labels).float().mean().item()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 28,
      "metadata": {
        "id": "5VzTQxAR5HoT"
      },
      "outputs": [],
      "source": [
        "class SAGELayer(nn.Module):\n",
        "    def __init__(self, ndim_in, edims, ndim_out, activation):\n",
        "        super(SAGELayer, self).__init__()\n",
        "        ### force to outut fix dimensions\n",
        "        self.W_msg = nn.Linear(ndim_in + edims, ndim_out)\n",
        "        ### apply weight\n",
        "        self.W_apply = nn.Linear(ndim_in + ndim_out, ndim_out)\n",
        "        self.activation = activation\n",
        "\n",
        "    def message_func(self, edges):\n",
        "        return {'m': self.W_msg(th.cat([edges.src['h'], edges.data['h']], 2))}\n",
        "\n",
        "    def forward(self, g_dgl, nfeats, efeats):\n",
        "        with g_dgl.local_scope():\n",
        "            g = g_dgl\n",
        "            g.ndata['h'] = nfeats\n",
        "            g.edata['h'] = efeats\n",
        "            # Eq4\n",
        "            g.update_all(self.message_func, fn.mean('m', 'h_neigh'))\n",
        "            # Eq5          \n",
        "            g.ndata['h'] = F.relu(self.W_apply(th.cat([g.ndata['h'], g.ndata['h_neigh']], 2)))\n",
        "            return g.ndata['h']\n",
        "\n",
        "\n",
        "class SAGE(nn.Module):\n",
        "    def __init__(self, ndim_in, ndim_out, edim, activation, dropout):\n",
        "        super(SAGE, self).__init__()\n",
        "        self.layers = nn.ModuleList()\n",
        "        self.layers.append(SAGELayer(ndim_in, edim, 128, activation))\n",
        "        self.layers.append(SAGELayer(128, edim, ndim_out, activation))\n",
        "        self.dropout = nn.Dropout(p=dropout)\n",
        "\n",
        "    def forward(self, g, nfeats, efeats):\n",
        "        for i, layer in enumerate(self.layers):\n",
        "            if i != 0:\n",
        "                nfeats = self.dropout(nfeats)\n",
        "            nfeats = layer(g, nfeats, efeats)\n",
        "        return nfeats.sum(1)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 29,
      "metadata": {
        "id": "hrLYvze5wwMi"
      },
      "outputs": [],
      "source": [
        "class MLPPredictor(nn.Module):\n",
        "    def __init__(self, in_features, out_classes):\n",
        "        super().__init__()\n",
        "        self.W = nn.Linear(in_features * 2, out_classes)\n",
        "\n",
        "    def apply_edges(self, edges):\n",
        "        h_u = edges.src['h']\n",
        "        h_v = edges.dst['h']\n",
        "        score = self.W(th.cat([h_u, h_v], 1))\n",
        "        return {'score': score}\n",
        "\n",
        "    def forward(self, graph, h):\n",
        "        with graph.local_scope():\n",
        "            graph.ndata['h'] = h\n",
        "            graph.apply_edges(self.apply_edges)\n",
        "            return graph.edata['score']"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 30,
      "metadata": {
        "id": "GPLg-kCcwxLa"
      },
      "outputs": [],
      "source": [
        "G.ndata['h'] = th.reshape(G.ndata['h'], (G.ndata['h'].shape[0], 1,G.ndata['h'].shape[1]))\n",
        "G.edata['h'] = th.reshape(G.edata['h'], (G.edata['h'].shape[0], 1,G.edata['h'].shape[1]))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 31,
      "metadata": {
        "id": "SwdZs785w1dT"
      },
      "outputs": [],
      "source": [
        "class Model(nn.Module):\n",
        "    def __init__(self, ndim_in, ndim_out, edim, activation, dropout):\n",
        "        super().__init__()\n",
        "        self.gnn = SAGE(ndim_in, ndim_out, edim, activation, dropout)\n",
        "        self.pred = MLPPredictor(ndim_out, 2)\n",
        "    def forward(self, g, nfeats, efeats):\n",
        "        h = self.gnn(g, nfeats, efeats)\n",
        "        return self.pred(g, h)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 32,
      "metadata": {
        "id": "BEw7J1Z45R62"
      },
      "outputs": [],
      "source": [
        "from sklearn.utils import class_weight\n",
        "class_weights = class_weight.compute_class_weight('balanced',\n",
        "                                                 np.unique(G.edata['label'].cpu().numpy()),\n",
        "                                                 G.edata['label'].cpu().numpy())"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 33,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "IZ39m_ib5VFV",
        "outputId": "f5cd4888-7824-4762-8771-905577300e16"
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "array([21.65086074,  0.51181985])"
            ]
          },
          "execution_count": 33,
          "metadata": {
            "tags": []
          },
          "output_type": "execute_result"
        }
      ],
      "source": [
        "class_weights"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 34,
      "metadata": {
        "id": "Cti0vAFYw3A0"
      },
      "outputs": [],
      "source": [
        "class_weights = th.FloatTensor(class_weights).cuda()\n",
        "criterion = nn.CrossEntropyLoss(weight=class_weights)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 35,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Rj3DHIZmw4IM",
        "outputId": "160b87cf-89c4-4dba-8be6-6fa6bc19442a"
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "device(type='cuda', index=0)"
            ]
          },
          "execution_count": 35,
          "metadata": {
            "tags": []
          },
          "output_type": "execute_result"
        }
      ],
      "source": [
        "G = G.to('cuda:0')\n",
        "G.device"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 36,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "qdlVG3JOw5Qj",
        "outputId": "73b046c5-aa9b-4017-9ae8-0d5525a71d2b"
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "device(type='cuda', index=0)"
            ]
          },
          "execution_count": 36,
          "metadata": {
            "tags": []
          },
          "output_type": "execute_result"
        }
      ],
      "source": [
        "G.ndata['h'].device\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 37,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "dvt3pnXmw6U7",
        "outputId": "de3250eb-f3f0-48f6-96ce-ec0232af5c7b"
      },
      "outputs": [
        {
          "data": {
            "text/plain": [
              "device(type='cuda', index=0)"
            ]
          },
          "execution_count": 37,
          "metadata": {
            "tags": []
          },
          "output_type": "execute_result"
        }
      ],
      "source": [
        "G.edata['h'].device\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 59,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "-_eTiHzWw8Cz",
        "outputId": "03e07a05-03dc-4e26-e389-d7c02e542acd"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Training acc: 0.917657732963562\n",
            "Training acc: 0.9214499592781067\n",
            "Training acc: 0.9220617413520813\n",
            "Training acc: 0.9209012389183044\n",
            "Training acc: 0.9199811816215515\n",
            "Training acc: 0.9219117760658264\n",
            "Training acc: 0.9213380813598633\n",
            "Training acc: 0.9229342341423035\n",
            "Training acc: 0.9236853122711182\n",
            "Training acc: 0.9310590624809265\n",
            "Training acc: 0.9283750057220459\n",
            "Training acc: 0.9307484030723572\n",
            "Training acc: 0.9339216947555542\n",
            "Training acc: 0.9336300492286682\n",
            "Training acc: 0.9345822930335999\n",
            "Training acc: 0.9322493672370911\n",
            "Training acc: 0.9349703192710876\n",
            "Training acc: 0.931145966053009\n",
            "Training acc: 0.9312126040458679\n",
            "Training acc: 0.9338704943656921\n",
            "Training acc: 0.9308186173439026\n",
            "Training acc: 0.9341264367103577\n",
            "Training acc: 0.9359832406044006\n",
            "Training acc: 0.9327052235603333\n",
            "Training acc: 0.9318863153457642\n",
            "Training acc: 0.9356821179389954\n",
            "Training acc: 0.9337419867515564\n",
            "Training acc: 0.9338050484657288\n",
            "Training acc: 0.9354238510131836\n",
            "Training acc: 0.9327445030212402\n",
            "Training acc: 0.933546781539917\n",
            "Training acc: 0.9324278831481934\n",
            "Training acc: 0.9349667429924011\n",
            "Training acc: 0.9356011748313904\n",
            "Training acc: 0.9337181448936462\n",
            "Training acc: 0.9347203969955444\n",
            "Training acc: 0.934268057346344\n",
            "Training acc: 0.9349667429924011\n",
            "Training acc: 0.9356761574745178\n",
            "Training acc: 0.935248851776123\n",
            "Training acc: 0.9358094930648804\n",
            "Training acc: 0.9349513053894043\n",
            "Training acc: 0.9347084760665894\n",
            "Training acc: 0.9349203109741211\n",
            "Training acc: 0.9346882104873657\n",
            "Training acc: 0.9354416728019714\n",
            "Training acc: 0.9368842840194702\n",
            "Training acc: 0.9356821179389954\n",
            "Training acc: 0.9357939958572388\n",
            "Training acc: 0.9386221170425415\n",
            "Training acc: 0.9356309175491333\n",
            "Training acc: 0.935165524482727\n",
            "Training acc: 0.934429943561554\n",
            "Training acc: 0.9352143406867981\n"
          ]
        }
      ],
      "source": [
        "node_features = G.ndata['h']\n",
        "edge_features = G.edata['h']\n",
        "\n",
        "edge_label = G.edata['label']\n",
        "train_mask = G.edata['train_mask']\n",
        "\n",
        "model = Model(G.ndata['h'].shape[2], 128, G.ndata['h'].shape[2], F.relu, 0.2).cuda()\n",
        "opt = th.optim.Adam(model.parameters())\n",
        "\n",
        "for epoch in range(1,5500):\n",
        "    pred = model(G, node_features,edge_features).cuda()\n",
        "    loss = criterion(pred[train_mask] ,edge_label[train_mask])\n",
        "    opt.zero_grad()\n",
        "    loss.backward()\n",
        "    opt.step()\n",
        "    if epoch % 100 == 0:\n",
        "      print('Training acc:', compute_accuracy(pred[train_mask], edge_label[train_mask]))\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 39,
      "metadata": {
        "id": "p7gYo6lVtHCN"
      },
      "outputs": [],
      "source": [
        "X_test = encoder.transform(X_test)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 40,
      "metadata": {
        "id": "OUGIEbMFtSnf"
      },
      "outputs": [],
      "source": [
        "X_test[cols_to_norm] = scaler.transform(X_test[cols_to_norm])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 41,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 439
        },
        "id": "VlyqlEqjtb9s",
        "outputId": "3330aba4-3495-4d95-ed26-8dd30ea3c3d0"
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "<div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>IPV4_SRC_ADDR</th>\n",
              "      <th>IPV4_DST_ADDR</th>\n",
              "      <th>PROTOCOL</th>\n",
              "      <th>L7_PROTO</th>\n",
              "      <th>IN_BYTES</th>\n",
              "      <th>OUT_BYTES</th>\n",
              "      <th>IN_PKTS</th>\n",
              "      <th>OUT_PKTS</th>\n",
              "      <th>TCP_FLAGS</th>\n",
              "      <th>FLOW_DURATION_MILLISECONDS</th>\n",
              "      <th>label</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>175006</th>\n",
              "      <td>172.20.224.183:52476</td>\n",
              "      <td>192.168.100.6:3371</td>\n",
              "      <td>0.242607</td>\n",
              "      <td>0.041512</td>\n",
              "      <td>-0.017305</td>\n",
              "      <td>-0.008442</td>\n",
              "      <td>-0.045637</td>\n",
              "      <td>-0.027054</td>\n",
              "      <td>0.343039</td>\n",
              "      <td>0.496716</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>42610</th>\n",
              "      <td>172.20.88.47:42656</td>\n",
              "      <td>192.168.100.3:80</td>\n",
              "      <td>0.242607</td>\n",
              "      <td>0.254635</td>\n",
              "      <td>-0.016078</td>\n",
              "      <td>-0.007523</td>\n",
              "      <td>-0.025459</td>\n",
              "      <td>-0.009069</td>\n",
              "      <td>0.321493</td>\n",
              "      <td>0.488632</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>343626</th>\n",
              "      <td>172.24.83.27:59940</td>\n",
              "      <td>192.168.100.7:7402</td>\n",
              "      <td>0.242607</td>\n",
              "      <td>0.041512</td>\n",
              "      <td>-0.017305</td>\n",
              "      <td>-0.008442</td>\n",
              "      <td>-0.045637</td>\n",
              "      <td>-0.027054</td>\n",
              "      <td>0.343039</td>\n",
              "      <td>0.496716</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>125174</th>\n",
              "      <td>172.17.188.133:14622</td>\n",
              "      <td>192.168.100.3:12344</td>\n",
              "      <td>0.242607</td>\n",
              "      <td>0.041512</td>\n",
              "      <td>-0.017313</td>\n",
              "      <td>-0.008442</td>\n",
              "      <td>-0.045637</td>\n",
              "      <td>-0.027054</td>\n",
              "      <td>0.343039</td>\n",
              "      <td>0.496716</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>118951</th>\n",
              "      <td>172.28.20.54:53588</td>\n",
              "      <td>192.168.100.6:5002</td>\n",
              "      <td>0.242607</td>\n",
              "      <td>0.041512</td>\n",
              "      <td>-0.017305</td>\n",
              "      <td>-0.008442</td>\n",
              "      <td>-0.045637</td>\n",
              "      <td>-0.027054</td>\n",
              "      <td>0.343039</td>\n",
              "      <td>0.496716</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>...</th>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "      <td>...</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>190354</th>\n",
              "      <td>172.19.134.92:56591</td>\n",
              "      <td>192.168.100.5:50300</td>\n",
              "      <td>0.242607</td>\n",
              "      <td>0.041512</td>\n",
              "      <td>-0.017305</td>\n",
              "      <td>-0.008442</td>\n",
              "      <td>-0.045637</td>\n",
              "      <td>-0.027054</td>\n",
              "      <td>0.343039</td>\n",
              "      <td>0.496716</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>568549</th>\n",
              "      <td>172.16.123.10:34808</td>\n",
              "      <td>192.168.100.3:80</td>\n",
              "      <td>0.242607</td>\n",
              "      <td>0.254635</td>\n",
              "      <td>-0.015753</td>\n",
              "      <td>-0.007441</td>\n",
              "      <td>-0.021424</td>\n",
              "      <td>-0.003074</td>\n",
              "      <td>0.321493</td>\n",
              "      <td>-2.080333</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>302561</th>\n",
              "      <td>172.24.94.101:62675</td>\n",
              "      <td>192.168.100.6:211</td>\n",
              "      <td>0.242607</td>\n",
              "      <td>0.041512</td>\n",
              "      <td>-0.017305</td>\n",
              "      <td>-0.008442</td>\n",
              "      <td>-0.045637</td>\n",
              "      <td>-0.027054</td>\n",
              "      <td>0.343039</td>\n",
              "      <td>0.496716</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>451022</th>\n",
              "      <td>172.22.196.215:37508</td>\n",
              "      <td>192.168.100.3:42510</td>\n",
              "      <td>0.242607</td>\n",
              "      <td>0.041512</td>\n",
              "      <td>-0.017305</td>\n",
              "      <td>-0.008442</td>\n",
              "      <td>-0.045637</td>\n",
              "      <td>-0.027054</td>\n",
              "      <td>0.343039</td>\n",
              "      <td>0.496716</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>80381</th>\n",
              "      <td>172.16.70.182:64088</td>\n",
              "      <td>192.168.100.6:406</td>\n",
              "      <td>0.242607</td>\n",
              "      <td>0.041512</td>\n",
              "      <td>-0.017305</td>\n",
              "      <td>-0.008442</td>\n",
              "      <td>-0.045637</td>\n",
              "      <td>-0.027054</td>\n",
              "      <td>0.343039</td>\n",
              "      <td>0.496716</td>\n",
              "      <td>1</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "<p>180030 rows × 11 columns</p>\n",
              "</div>"
            ],
            "text/plain": [
              "               IPV4_SRC_ADDR  ... label\n",
              "175006  172.20.224.183:52476  ...     1\n",
              "42610     172.20.88.47:42656  ...     1\n",
              "343626    172.24.83.27:59940  ...     1\n",
              "125174  172.17.188.133:14622  ...     1\n",
              "118951    172.28.20.54:53588  ...     1\n",
              "...                      ...  ...   ...\n",
              "190354   172.19.134.92:56591  ...     1\n",
              "568549   172.16.123.10:34808  ...     1\n",
              "302561   172.24.94.101:62675  ...     1\n",
              "451022  172.22.196.215:37508  ...     1\n",
              "80381    172.16.70.182:64088  ...     1\n",
              "\n",
              "[180030 rows x 11 columns]"
            ]
          },
          "execution_count": 41,
          "metadata": {
            "tags": []
          },
          "output_type": "execute_result"
        }
      ],
      "source": [
        "X_test"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 42,
      "metadata": {
        "id": "q5CMxVe5xIDb"
      },
      "outputs": [],
      "source": [
        "X_test['h'] = X_test[ cols_to_norm ].values.tolist()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 43,
      "metadata": {
        "id": "VsAmtLAbxN_6"
      },
      "outputs": [],
      "source": [
        "G_test = nx.from_pandas_edgelist(X_test, \"IPV4_SRC_ADDR\", \"IPV4_DST_ADDR\", ['h','label'],create_using=nx.MultiGraph())\n",
        "G_test = G_test.to_directed()\n",
        "G_test = from_networkx(G_test,edge_attrs=['h','label'] )\n",
        "actual = G_test.edata.pop('label')\n",
        "G_test.ndata['feature'] = th.ones(G_test.num_nodes(), G.ndata['h'].shape[2])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 44,
      "metadata": {
        "id": "Eeux6JIxxQtC"
      },
      "outputs": [],
      "source": [
        "G_test.ndata['feature'] = th.reshape(G_test.ndata['feature'], (G_test.ndata['feature'].shape[0], 1, G_test.ndata['feature'].shape[1]))"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 45,
      "metadata": {
        "id": "PBETQI3YxYay"
      },
      "outputs": [],
      "source": [
        "G_test.edata['h'] = th.reshape(G_test.edata['h'], (G_test.edata['h'].shape[0], 1, G_test.edata['h'].shape[1]))\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 46,
      "metadata": {
        "id": "qlTOyVN6xZZB"
      },
      "outputs": [],
      "source": [
        "G_test = G_test.to('cuda:0')\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 60,
      "metadata": {
        "id": "QyugNIt9xac6"
      },
      "outputs": [],
      "source": [
        "import timeit\n",
        "start_time = timeit.default_timer()\n",
        "node_features_test = G_test.ndata['feature']\n",
        "edge_features_test = G_test.edata['h']\n",
        "test_pred = model(G_test, node_features_test, edge_features_test).cuda()\n",
        "elapsed = timeit.default_timer() - start_time"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 61,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "KecCvilSxcFK",
        "outputId": "685bdc3d-254d-423d-9222-bb48e7255621"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "0.029059830000278453 seconds\n"
          ]
        }
      ],
      "source": [
        "print(str(elapsed) + ' seconds')\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 62,
      "metadata": {
        "id": "BNQLnLoAxdST"
      },
      "outputs": [],
      "source": [
        "test_pred = test_pred.argmax(1)\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 63,
      "metadata": {
        "id": "9dtggXXsxevx"
      },
      "outputs": [],
      "source": [
        "test_pred = th.Tensor.cpu(test_pred).detach().numpy()\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 64,
      "metadata": {
        "id": "5TGb_KWRxfzS"
      },
      "outputs": [],
      "source": [
        "actual = [\"Normal\" if i == 0 else \"Attack\" for i in actual]\n",
        "test_pred = [\"Normal\" if i == 0 else \"Attack\" for i in test_pred]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 65,
      "metadata": {
        "id": "n7z7tHTPxhBC"
      },
      "outputs": [],
      "source": [
        "from sklearn.metrics import plot_confusion_matrix\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 66,
      "metadata": {
        "id": "uMRairwzxiBC"
      },
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "\n",
        "\n",
        "def plot_confusion_matrix(cm,\n",
        "                          target_names,\n",
        "                          title='Confusion matrix',\n",
        "                          cmap=None,\n",
        "                          normalize=True):\n",
        "    \n",
        "    import matplotlib.pyplot as plt\n",
        "    import numpy as np\n",
        "    import itertools\n",
        "\n",
        "    accuracy = np.trace(cm) / float(np.sum(cm))\n",
        "    misclass = 1 - accuracy\n",
        "\n",
        "    if cmap is None:\n",
        "        cmap = plt.get_cmap('Blues')\n",
        "\n",
        "    plt.figure(figsize=(12, 12))\n",
        "    plt.imshow(cm, interpolation='nearest', cmap=cmap)\n",
        "    plt.title(title)\n",
        "    plt.colorbar()\n",
        "\n",
        "    if target_names is not None:\n",
        "        tick_marks = np.arange(len(target_names))\n",
        "        plt.xticks(tick_marks, target_names, rotation=45)\n",
        "        plt.yticks(tick_marks, target_names)\n",
        "\n",
        "    if normalize:\n",
        "        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]\n",
        "\n",
        "\n",
        "    thresh = cm.max() / 1.5 if normalize else cm.max() / 2\n",
        "    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):\n",
        "        if normalize:\n",
        "            plt.text(j, i, \"{:0.4f}\".format(cm[i, j]),\n",
        "                     horizontalalignment=\"center\",\n",
        "                     color=\"white\" if cm[i, j] > thresh else \"black\")\n",
        "        else:\n",
        "            plt.text(j, i, \"{:,}\".format(cm[i, j]),\n",
        "                     horizontalalignment=\"center\",\n",
        "                     color=\"white\" if cm[i, j] > thresh else \"black\")\n",
        "\n",
        "\n",
        "    plt.tight_layout()\n",
        "    plt.ylabel('True label')\n",
        "    plt.xlabel('Predicted label\\naccuracy={:0.4f}; misclass={:0.4f}'.format(accuracy, misclass))\n",
        "    plt.show()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 67,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 873
        },
        "id": "KNCkVWyqxjaR",
        "outputId": "ae48a136-c1ac-4754-b499-b287f7c5f24f"
      },
      "outputs": [
        {
          "data": {
            "image/png": "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AIMmKAIAAAZNUAQAAAyaNUUAADBCKlpy902mCAAAGDRBEQAAMGjK5wAAYKSU8rmeyRQBAACDJigCAAAGTfkcAACMGNVz/RIUwf2wwvJz8t+ffkOWX35O5syenS/99/l573+cms8cum+223LjzJt/b865+IocdOjxmT//vqy+6oo58r37ZqP118qc2bNz2DHfzLGn/OgP7rvGqivl8INfnC0fs35aS1797uNy5kWX552v+Ys8988fn/tay/U33ZYDDv5srrn+1uy9x/Z54yuelarK7Xfende978T8+OdXz8AnAgzR1VddmYNe9Te54bprU1V56StemQNe89q8/z0H57RTv5JZs2Zl7bXXzcf+41N5xPqPXOTam268Mfu/fO9ccN452fvFL88/f+ijC4+975B35OTjj8stt9ycy6+5eeH4f/z7YTnu6CMze86cPHztdXLYx4/IRhs/qrf3Czz0VWttpucwo2atvG5bYfMXzvQ0eBBZZaXlc8ddv8ucObPyrSPfmDf/6+ez1hor5/Tv/yRJcvQ/vyLfP29uPnny9/P3f/PsrLHqSnn7x76ctddaNRd+6R3Z5Jlvy7z59y5yz08e8rL84Py5OepLP8xyc2Zn5RWXz62335XVVlkxt91xd5LkNfv8ebZ49Pp53aEnZKdtNs1PL/tNbrntrjz7yVvm7a96Tp728g/2/lnw4HbF9z4y01PgQera31yTa3/zmzx+2yfk9ttuy7OetmOOOv7zeeQjN8xqq6+eJPnk4f+en//s0vzrYR9f5No77rgjF190QX76k0vy059cskhQdM5ZZ2ajjTfOTk/YcpGg6Pvf+062236HrLzyyjnqU/+ZH3z/u/nkUZ/r583ykLTe6suf21rbfqbnMZmVH7l5e+wBn5jpaSzRhe9+5kh/jveHNUVwP91x1++SJMvNmZ05c2antbYwIEqScy6+Ihusu1aSpCVZdZUVkiSrrLRCbr71zsy/975F7rf6qivmKds9Jkd96YdJknnz782tt9+VJAsDoiRZeaUVsuAfMX504eW55baxc8666PJssN6a0/BOASa23iPWz+O3fUKSZNXVVstmm2+R3/z61wsDoiS58847Juyetcoqq2THnZ+cFVZc8Q+Obb/DjlnvEev/wfhTnrZLVl555STJE/9sh1xztcw4sGwpn4P7adasyv9+7h/zmI3WyX+e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",
            "text/plain": [
              "<Figure size 864x864 with 2 Axes>"
            ]
          },
          "metadata": {
            "needs_background": "light",
            "tags": []
          },
          "output_type": "display_data"
        }
      ],
      "source": [
        "from sklearn.metrics import confusion_matrix\n",
        "\n",
        "plot_confusion_matrix(cm = confusion_matrix(actual, test_pred), \n",
        "                      normalize    = False,\n",
        "                      target_names = np.unique(actual),\n",
        "                      title        = \"Confusion Matrix\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "yO55tl6rnD3-"
      },
      "outputs": [],
      "source": []
    }
  ],
  "metadata": {
    "accelerator": "GPU",
    "colab": {
      "collapsed_sections": [],
      "machine_shape": "hm",
      "name": "unsw_bot_iot_binary_mean_agg.ipynb",
      "provenance": []
    },
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.8.5"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
